﻿using System;
using System.IO;
using System.Reflection;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;

namespace Notoric.ViewModel.Internal
{
    /// <summary>
    /// Simple helper class that loads embedded bitmap resources.
    /// </summary>
    internal static class EmbeddedBitmapLoader
    {
        /// <summary>
        /// Loads a given bitmap resource.
        /// </summary>
        /// <param name="bitmapName">
        /// <para>
        /// Type: <see cref="System.String"/>
        /// </para>
        /// <para>
        /// The case-sensitive name of the embedded resource being requested relative to the Resources directory.
        /// </para>
        /// </param>
        /// <returns>
        /// <para>
        /// Type: <see cref="ImageSource"/>
        /// </para>
        /// <para>
        /// The loaded image source.
        /// </para>
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="bitmapName"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="FileNotFoundException">
        /// <paramref name="bitmapName"/> was not found.
        /// </exception>
        /// <exception cref="FileLoadException">
        /// A file that was found could not be loaded.
        /// </exception>
        public static ImageSource Load(string bitmapName)
        {
            if (bitmapName == null)
                throw new ArgumentNullException("bitmapName");

            var assembly = Assembly.GetExecutingAssembly();
            var stream = assembly.GetManifestResourceStream("Notoric.ViewModel.Resources." + bitmapName);
            var extension = Path.GetExtension(bitmapName);

            BitmapDecoder decoder = null;

            switch (extension)
            {
                case ".bmp":
                    decoder = new BmpBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
                case ".jpg":
                case ".jpeg":
                    decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
                case ".gif":
                    decoder = new GifBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
                case ".png":
                    decoder = new PngBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
                case ".tif":
                    decoder = new TiffBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
                case ".wdp":
                    decoder = new TiffBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
                case ".ico":
                    decoder = new IconBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default);
                    break;
            }
            
            if (decoder != null && decoder.Frames.Count > 0)
                return decoder.Frames[0];

            return null;
        }

        /// <summary>
        /// Loads a given bitmap resource as <see cref="Image"/>.
        /// </summary>
        /// <param name="bitmapName">
        /// <para>
        /// Type: <see cref="System.String"/>
        /// </para>
        /// <para>
        /// The case-sensitive name of the embedded resource being requested relative to the Resources directory.
        /// </para>
        /// </param>
        /// <param name="width">
        /// <para>
        /// Type: <see cref="Int32"/>
        /// </para>
        /// <para>
        /// The width that should be set to the image.
        /// Default is <i>Auto</i>.
        /// </para>
        /// </param>
        /// <param name="height">
        /// <para>
        /// Type: <see cref="Int32"/>
        /// </para>
        /// <para>
        /// The height that should be set to the image.
        /// Default is <i>Auto</i>.
        /// </para>
        /// </param>
        /// <returns>
        /// <para>
        /// Type: <see cref="Image"/>
        /// </para>
        /// <para>
        /// The loaded image source.
        /// </para>
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="bitmapName"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="FileNotFoundException">
        /// <paramref name="bitmapName"/> was not found.
        /// </exception>
        /// <exception cref="FileLoadException">
        /// A file that was found could not be loaded.
        /// </exception>
        public static Image LoadImage(string bitmapName, int width = -1, int height = -1)
        {
            Image image = new Image();
            image.Source = Load(bitmapName);

            if (width > 0)
                image.Width = width;
            if (height > 0)
                image.Height = height;

            return image;
        }
    }
}
